package com.graden.background.common.conf.aop.sso;

import com.graden.background.service.sysuser.ISysUserService;
import com.graden.background.common.utils.exception.ExceptionManager;
import com.graden.background.repository.systoken.entity.SysToken;
import com.graden.background.repository.sysuser.entity.SysUser;
import com.graden.background.service.systoken.ISysTokenService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Objects;

/**
 * Created by Tom on 2017/12/6.
 * 校验并获取用户信息Aop
 */
@Component
@Aspect
@Slf4j
@Order(1)
public class CheckTokenAop {

	@Resource
	ExceptionManager exceptionManager;

	@Resource
	ISysTokenService iSysTokenService;

	@Resource
	ISysUserService iSysUserService;

	@Resource
	ApplicationContext applicationContext;


	@Around(value = "execution(* com.itfuture.chainserviceview.controller..*.*(..)) " +
			"&& !execution(* com.graden.background.controller.sysuser.SysUserController.loginUser(..))")
	@Transactional
	public Object checkTokenAndInjectUser(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

		// 从域的Header中获取ticket
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		String token = request.getHeader("token");
		log.info("token - " + token);
		if (StringUtils.isEmpty(token)) {
			throw exceptionManager.create("LOGIN_0001");
		}

		SysToken sysToken = iSysTokenService.getOneByToken(token);

		if (Objects.nonNull(sysToken)) {

			AopResourceUserInfoBean aopResourceUserInfoBean = applicationContext.getBean(AopResourceUserInfoBean.class);
			if (Objects.isNull(aopResourceUserInfoBean) || Objects.isNull(aopResourceUserInfoBean.getBipCode())) {
				throw exceptionManager.create("LOGIN_0008");
			}

			SysUser sysUser = iSysUserService.getSysUserByBipCode(sysToken.getBipCode());

			//判断账号是否可用
			if (sysUser == null) {
				throw exceptionManager.create("AUTH_0004");
			}

			//判断时间是否过期
			long tokeTime = sysToken.getRefreshTime().toEpochSecond(ZoneOffset.of("+8"));
			long nowTime = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
			long time = nowTime - tokeTime;
			if (time > 60 * 60 * 2) { //过期时间设为两个小时
				throw exceptionManager.create("LOGIN_0008");
			}

			//更新token
			iSysTokenService.tokenRefresh(token);
			HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
			response.setHeader("token", token);

		} else {
			AopResourceUserInfoBean aopResourceUserInfoBean = applicationContext.getBean(AopResourceUserInfoBean.class);
			if (!StringUtils.isEmpty(aopResourceUserInfoBean.getBipCode())) { //确认之前一直使用，后面因为其他人操作导致Token改变了

				if (!iSysTokenService.getOneByBipCode(aopResourceUserInfoBean.getBipCode()).getToken().equals(token)) {
					throw exceptionManager.create("LOGIN_0011");
				}
			}
			throw exceptionManager.create("LOGIN_0001");
		}

		return proceedingJoinPoint.proceed();
	}

}


